// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.

#include <EngineList.h>
#include <DataNode.h>
#include <EngineProperties.h>

// ****************************************************************************
// Method: EngineList::EngineList
//
// Purpose:
//   Init utility for the EngineList class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void EngineList::Init()
{

    EngineList::SelectAll();
}

// ****************************************************************************
// Method: EngineList::EngineList
//
// Purpose:
//   Copy utility for the EngineList class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void EngineList::Copy(const EngineList &obj)
{
    AttributeGroupVector::const_iterator pos;

    engineName = obj.engineName;
    simulationName = obj.simulationName;
    // *** Copy the properties field ***
    // Delete the AttributeGroup objects and clear the vector.
    for(pos = properties.begin(); pos != properties.end(); ++pos)
        delete *pos;
    properties.clear();
    if(obj.properties.size() > 0)
        properties.reserve(obj.properties.size());
    // Duplicate the properties from obj.
    for(pos = obj.properties.begin(); pos != obj.properties.end(); ++pos)
    {
        EngineProperties *oldEngineProperties = (EngineProperties *)(*pos);
        EngineProperties *newEngineProperties = new EngineProperties(*oldEngineProperties);
        properties.push_back(newEngineProperties);
    }


    EngineList::SelectAll();
}

// Type map format string
const char *EngineList::TypeMapFormatString = ENGINELIST_TMFS;
const AttributeGroup::private_tmfs_t EngineList::TmfsStruct = {ENGINELIST_TMFS};


// ****************************************************************************
// Method: EngineList::EngineList
//
// Purpose:
//   Default constructor for the EngineList class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

EngineList::EngineList() :
    AttributeSubject(EngineList::TypeMapFormatString)
{
    EngineList::Init();
}

// ****************************************************************************
// Method: EngineList::EngineList
//
// Purpose:
//   Constructor for the derived classes of EngineList class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

EngineList::EngineList(private_tmfs_t tmfs) :
    AttributeSubject(tmfs.tmfs)
{
    EngineList::Init();
}

// ****************************************************************************
// Method: EngineList::EngineList
//
// Purpose:
//   Copy constructor for the EngineList class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

EngineList::EngineList(const EngineList &obj) :
    AttributeSubject(EngineList::TypeMapFormatString)
{
    EngineList::Copy(obj);
}

// ****************************************************************************
// Method: EngineList::EngineList
//
// Purpose:
//   Copy constructor for derived classes of the EngineList class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

EngineList::EngineList(const EngineList &obj, private_tmfs_t tmfs) :
    AttributeSubject(tmfs.tmfs)
{
    EngineList::Copy(obj);
}

// ****************************************************************************
// Method: EngineList::~EngineList
//
// Purpose:
//   Destructor for the EngineList class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

EngineList::~EngineList()
{
    AttributeGroupVector::iterator pos;

    // Destroy the properties field.
    for(pos = properties.begin(); pos != properties.end(); ++pos)
        delete *pos;
}

// ****************************************************************************
// Method: EngineList::operator =
//
// Purpose:
//   Assignment operator for the EngineList class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

EngineList&
EngineList::operator = (const EngineList &obj)
{
    if (this == &obj) return *this;

    EngineList::Copy(obj);

    return *this;
}

// ****************************************************************************
// Method: EngineList::operator ==
//
// Purpose:
//   Comparison operator == for the EngineList class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
EngineList::operator == (const EngineList &obj) const
{
    bool properties_equal = (obj.properties.size() == properties.size());
    for(size_t i = 0; (i < properties.size()) && properties_equal; ++i)
    {
        // Make references to EngineProperties from AttributeGroup *.
        const EngineProperties &properties1 = *((const EngineProperties *)(properties[i]));
        const EngineProperties &properties2 = *((const EngineProperties *)(obj.properties[i]));
        properties_equal = (properties1 == properties2);
    }

    // Create the return value
    return ((engineName == obj.engineName) &&
            (simulationName == obj.simulationName) &&
            properties_equal);
}

// ****************************************************************************
// Method: EngineList::operator !=
//
// Purpose:
//   Comparison operator != for the EngineList class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
EngineList::operator != (const EngineList &obj) const
{
    return !(this->operator == (obj));
}

// ****************************************************************************
// Method: EngineList::TypeName
//
// Purpose:
//   Type name method for the EngineList class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

const std::string
EngineList::TypeName() const
{
    return "EngineList";
}

// ****************************************************************************
// Method: EngineList::CopyAttributes
//
// Purpose:
//   CopyAttributes method for the EngineList class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
EngineList::CopyAttributes(const AttributeGroup *atts)
{
    if(TypeName() != atts->TypeName())
        return false;

    // Call assignment operator.
    const EngineList *tmp = (const EngineList *)atts;
    *this = *tmp;

    return true;
}

// ****************************************************************************
// Method: EngineList::CreateCompatible
//
// Purpose:
//   CreateCompatible method for the EngineList class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeSubject *
EngineList::CreateCompatible(const std::string &tname) const
{
    AttributeSubject *retval = 0;
    if(TypeName() == tname)
        retval = new EngineList(*this);
    // Other cases could go here too.

    return retval;
}

// ****************************************************************************
// Method: EngineList::NewInstance
//
// Purpose:
//   NewInstance method for the EngineList class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeSubject *
EngineList::NewInstance(bool copy) const
{
    AttributeSubject *retval = 0;
    if(copy)
        retval = new EngineList(*this);
    else
        retval = new EngineList;

    return retval;
}

// ****************************************************************************
// Method: EngineList::SelectAll
//
// Purpose:
//   Selects all attributes.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void
EngineList::SelectAll()
{
    Select(ID_engineName,     (void *)&engineName);
    Select(ID_simulationName, (void *)&simulationName);
    Select(ID_properties,     (void *)&properties);
}

// ****************************************************************************
// Method: EngineList::CreateSubAttributeGroup
//
// Purpose:
//   This class contains a list of host names on which engines are running.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeGroup *
EngineList::CreateSubAttributeGroup(int)
{
    return new EngineProperties;
}

///////////////////////////////////////////////////////////////////////////////
// Persistence methods
///////////////////////////////////////////////////////////////////////////////

// ****************************************************************************
// Method: EngineList::CreateNode
//
// Purpose:
//   This method creates a DataNode representation of the object so it can be saved to a config file.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
EngineList::CreateNode(DataNode *parentNode, bool completeSave, bool forceAdd)
{
    if(parentNode == 0)
        return false;

    EngineList defaultObject;
    bool addToParent = false;
    // Create a node for EngineList.
    DataNode *node = new DataNode("EngineList");

    if(completeSave || !FieldsEqual(ID_engineName, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("engineName", engineName));
    }

    if(completeSave || !FieldsEqual(ID_simulationName, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("simulationName", simulationName));
    }

    if(completeSave || !FieldsEqual(ID_properties, &defaultObject))
    {
        addToParent = true;
        for(size_t i = 0; i < properties.size(); ++i)
            properties[i]->CreateNode(node, completeSave, true);
    }


    // Add the node to the parent node.
    if(addToParent || forceAdd)
        parentNode->AddNode(node);
    else
        delete node;

    return (addToParent || forceAdd);
}

// ****************************************************************************
// Method: EngineList::SetFromNode
//
// Purpose:
//   This method sets attributes in this object from values in a DataNode representation of the object.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void
EngineList::SetFromNode(DataNode *parentNode)
{
    if(parentNode == 0)
        return;

    DataNode *searchNode = parentNode->GetNode("EngineList");
    if(searchNode == 0)
        return;

    DataNode *node;
    DataNode **children;
    if((node = searchNode->GetNode("engineName")) != 0)
        SetEngineName(node->AsStringVector());
    if((node = searchNode->GetNode("simulationName")) != 0)
        SetSimulationName(node->AsStringVector());

    // Clear all the EnginePropertiess if we got any.
    bool clearedProperties = false;
    // Go through all of the children and construct a new
    // EngineProperties for each one of them.
    children = searchNode->GetChildren();
    if(children != 0)
    {
        for(int i = 0; i < searchNode->GetNumChildren(); ++i)
        {
            if(children[i]->GetKey() == std::string("EngineProperties"))
            {
                if (!clearedProperties)
                {
                    ClearProperties();
                    clearedProperties = true;
                }
                EngineProperties temp;
                temp.SetFromNode(children[i]);
                AddProperties(temp);
            }
        }
    }

}

///////////////////////////////////////////////////////////////////////////////
// Set property methods
///////////////////////////////////////////////////////////////////////////////

void
EngineList::SetEngineName(const stringVector &engineName_)
{
    engineName = engineName_;
    Select(ID_engineName, (void *)&engineName);
}

void
EngineList::SetSimulationName(const stringVector &simulationName_)
{
    simulationName = simulationName_;
    Select(ID_simulationName, (void *)&simulationName);
}

///////////////////////////////////////////////////////////////////////////////
// Get property methods
///////////////////////////////////////////////////////////////////////////////

const stringVector &
EngineList::GetEngineName() const
{
    return engineName;
}

stringVector &
EngineList::GetEngineName()
{
    return engineName;
}

const stringVector &
EngineList::GetSimulationName() const
{
    return simulationName;
}

stringVector &
EngineList::GetSimulationName()
{
    return simulationName;
}

const AttributeGroupVector &
EngineList::GetProperties() const
{
    return properties;
}

AttributeGroupVector &
EngineList::GetProperties()
{
    return properties;
}

///////////////////////////////////////////////////////////////////////////////
// Select property methods
///////////////////////////////////////////////////////////////////////////////

void
EngineList::SelectEngineName()
{
    Select(ID_engineName, (void *)&engineName);
}

void
EngineList::SelectSimulationName()
{
    Select(ID_simulationName, (void *)&simulationName);
}

void
EngineList::SelectProperties()
{
    Select(ID_properties, (void *)&properties);
}

///////////////////////////////////////////////////////////////////////////////
// AttributeGroupVector convenience methods.
///////////////////////////////////////////////////////////////////////////////

// ****************************************************************************
// Method: EngineList::AddProperties
//
// Purpose:
//   This class contains a list of host names on which engines are running.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void
EngineList::AddProperties(const EngineProperties &obj)
{
    EngineProperties *newEngineProperties = new EngineProperties(obj);
    properties.push_back(newEngineProperties);

    // Indicate that things have changed by selecting it.
    Select(ID_properties, (void *)&properties);
}

// ****************************************************************************
// Method: EngineList::ClearProperties
//
// Purpose:
//   This class contains a list of host names on which engines are running.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void
EngineList::ClearProperties()
{
    AttributeGroupVector::iterator pos;

    for(pos = properties.begin(); pos != properties.end(); ++pos)
        delete *pos;
    properties.clear();

    // Indicate that things have changed by selecting the list.
    Select(ID_properties, (void *)&properties);
}

// ****************************************************************************
// Method: EngineList::RemoveProperties
//
// Purpose:
//   This class contains a list of host names on which engines are running.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void
EngineList::RemoveProperties(int index)
{
    AttributeGroupVector::iterator pos = properties.begin();

    // Iterate through the vector "index" times.
    for(int i = 0; i < index; ++i)
        if(pos != properties.end()) ++pos;

    // If pos is still a valid iterator, remove that element.
    if(pos != properties.end())
    {
        delete *pos;
        properties.erase(pos);
    }

    // Indicate that things have changed by selecting the list.
    Select(ID_properties, (void *)&properties);
}

// ****************************************************************************
// Method: EngineList::GetNumProperties
//
// Purpose:
//   This class contains a list of host names on which engines are running.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

int
EngineList::GetNumProperties() const
{
    return (int)properties.size();
}

// ****************************************************************************
// Method: EngineList::GetProperties
//
// Purpose:
//   This class contains a list of host names on which engines are running.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

EngineProperties &
EngineList::GetProperties(int i)
{
    return *((EngineProperties *)properties[i]);
}

// ****************************************************************************
// Method: EngineList::GetProperties
//
// Purpose:
//   This class contains a list of host names on which engines are running.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

const EngineProperties &
EngineList::GetProperties(int i) const
{
    return *((EngineProperties *)properties[i]);
}

// ****************************************************************************
// Method: EngineList::operator []
//
// Purpose:
//   This class contains a list of host names on which engines are running.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

EngineProperties &
EngineList::operator [] (int i)
{
    return *((EngineProperties *)properties[i]);
}

// ****************************************************************************
// Method: EngineList::operator []
//
// Purpose:
//   This class contains a list of host names on which engines are running.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

const EngineProperties &
EngineList::operator [] (int i) const
{
    return *((EngineProperties *)properties[i]);
}

///////////////////////////////////////////////////////////////////////////////
// Keyframing methods
///////////////////////////////////////////////////////////////////////////////

// ****************************************************************************
// Method: EngineList::GetFieldName
//
// Purpose:
//   This method returns the name of a field given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

std::string
EngineList::GetFieldName(int index) const
{
    switch (index)
    {
    case ID_engineName:     return "engineName";
    case ID_simulationName: return "simulationName";
    case ID_properties:     return "properties";
    default:  return "invalid index";
    }
}

// ****************************************************************************
// Method: EngineList::GetFieldType
//
// Purpose:
//   This method returns the type of a field given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeGroup::FieldType
EngineList::GetFieldType(int index) const
{
    switch (index)
    {
    case ID_engineName:     return FieldType_stringVector;
    case ID_simulationName: return FieldType_stringVector;
    case ID_properties:     return FieldType_attVector;
    default:  return FieldType_unknown;
    }
}

// ****************************************************************************
// Method: EngineList::GetFieldTypeName
//
// Purpose:
//   This method returns the name of a field type given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

std::string
EngineList::GetFieldTypeName(int index) const
{
    switch (index)
    {
    case ID_engineName:     return "stringVector";
    case ID_simulationName: return "stringVector";
    case ID_properties:     return "attVector";
    default:  return "invalid index";
    }
}

// ****************************************************************************
// Method: EngineList::FieldsEqual
//
// Purpose:
//   This method compares two fields and return true if they are equal.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
EngineList::FieldsEqual(int index_, const AttributeGroup *rhs) const
{
    const EngineList &obj = *((const EngineList*)rhs);
    bool retval = false;
    switch (index_)
    {
    case ID_engineName:
        {  // new scope
        retval = (engineName == obj.engineName);
        }
        break;
    case ID_simulationName:
        {  // new scope
        retval = (simulationName == obj.simulationName);
        }
        break;
    case ID_properties:
        {  // new scope
        bool properties_equal = (obj.properties.size() == properties.size());
        for(size_t i = 0; (i < properties.size()) && properties_equal; ++i)
        {
            // Make references to EngineProperties from AttributeGroup *.
            const EngineProperties &properties1 = *((const EngineProperties *)(properties[i]));
            const EngineProperties &properties2 = *((const EngineProperties *)(obj.properties[i]));
            properties_equal = (properties1 == properties2);
        }

        retval = properties_equal;
        }
        break;
    default: retval = false;
    }

    return retval;
}

///////////////////////////////////////////////////////////////////////////////
// User-defined methods.
///////////////////////////////////////////////////////////////////////////////

